#ifndef __FEMSPACE_H__
#define __FEMSPACE_H__

#include "mesh.h"
#include "meshcomm.h"
#include "enumerations.h"
#include "base.h"

typedef SHAREDGEO SHAREDDOF;

typedef struct FEMSPACE_
{
    // FemType表示目前支持的有限元类型, 比如C_T_P1_2D,C_T_P1_3D,注意这里的定义规则
    FEMTYPE FemType;
    //本进程中的自由度个数
    INT NumDOF;
    INT MyNumDOF;
    //全局的自由度个数
    INT GlobalNumDOF;
    //本进程中全局编号的起点和终点，[GDOFstart,GDOFend-1]的全局编号都属于本进程
    //本进程作为宿主进程的自由度都落在上面区间中。
    INT GDOFstart, GDOFend;
    //有限元空间所依赖的网格
    MESH *Mesh;
    //边界函数类型：应该还需要跟有限元函数结合在一起，
    // INT NumBoundTypes;
    BOUNDARYTYPEFUNCTION *BoundType;
    //有限元基函数, 这里的基函数是与FemType对应的
    BASE *Base;
    //自由度信息: BeginIndex存储每个单元在LocalNumbers和GlobalNumber中的起始位置
    INT *BeginIndex;
    //每个单元在本进程中的自由度编号
    INT *LocalIndex;
    //与每个局部自由度所对应的全局编号: GlobalIndex[k]表示第k个局部自由度对应的全局编号
    INT *GlobalIndex;  
    //共享自由度信息
    SHAREDDOF *SharedDOF;
    //下面的这个成员应该是在程序实现中进行应用
    INT Is_Copy;
    // dirichlet boundary
    bool delete_dirichletbd;
    INT dirichletbdnum;
    INT *dirichletbdindex;
} FEMSPACE;
FEMSPACE *FEMSpaceBuild(MESH *mesh, FEMTYPE FemType, BOUNDARYTYPEFUNCTION *BoundType);
FEMSPACE *FEMSpaceBuildbyBase(MESH *mesh, BASE *Base, BOUNDARYTYPEFUNCTION *BoundCond);
void FEMSpaceDestroy(FEMSPACE **fespace);

BASE *BaseBuild(FEMTYPE FemType);

void BuildDOF1D(FEMSPACE *femspace);
void BuildDOF2D(FEMSPACE *femspace);
void BuildDOF3D(FEMSPACE *femspace);
void BuildSharedDOF(FEMSPACE *femspace);
void BuildDOFGlobalIndex(FEMSPACE *femspace);
void SharedDOFPrint(FEMSPACE *femspace, INT printrank);
void GetElementBoundaryInformation(FEMSPACE *femspace, INT ind, BOUNDARYTYPE *ElemBoundaryType, INT *DirichletBDInd);

void SetElemType(ELEMENT *Elem, FEMSPACE *FemSpace);
#endif